<!--菜单管理-->
<!--created by lx 2023/3/20-->
<template>
  <div class="list-card-container">
    <a-card title="菜单管理" class="general-card">
      <!-- 查询表单 -->
      <table-search :data-source="SEARCH_FORM" @change="searchMenu" />

      <!-- 表格 -->
      <AddDrawer
        clickword="新增"
        title="新增菜单"
        :data-source="ADD_MENU_FORM"
        style="margin-bottom: 16px"
        @change="addMenu"
      />
      <a-table
        :columns="COLUMNS_ROLE"
        :data="menuList"
        :expanded-keys="expandedRowKeys"
        row-key="id"
        :loading="loading"
        :scroll="{ x: 1560 }"
        @expand="onExpandRow"
        @expanded-change="onExpandChange"
      >
        <!-- 插槽：状态 -->
        <template #status="{ record }">
          <a-tag v-if="record.status === 0" color="#00b42a">启用</a-tag>
          <a-tag v-if="record.status === 1" color="#86909c">停用</a-tag>
        </template>

        <!-- 插槽: 菜单类型 -->
        <template #type="{ record }">
          <a-tag v-if="record.type === 1" color="green">目录</a-tag>
          <a-tag v-if="record.type === 2" color="cyan">菜单</a-tag>
          <a-tag v-if="record.type === 3" color="#165dff">按钮</a-tag>
        </template>

        <!--插槽，操作-->
        <template #operation="{ record }">
          <a-space>
            <AddDrawer
              v-if="record.type !== 3"
              :data-source="EDIT_MENU_FORM"
              :data-record="record"
              clickword="修改"
              title="修改菜单"
              click="link"
              icon="empty"
              @change="(req) => editMenu(req, record)"
            />
            <AddDrawer
              v-if="record.type === 3"
              :data-source="EDIT_BUTTON_FORM"
              :data-record="record"
              title="修改按钮"
              clickword="修改"
              narrow
              click="link"
              icon="empty"
              @change="(req) => editMenu(req, record)"
            />
            <a-popconfirm
              content="确定删除吗？"
              type="warning"
              @ok="deleteMenu(record)"
            >
              <a-link :disabled="(record.children || []).length > 0">
                删除
              </a-link>
            </a-popconfirm>
            <AddDrawer
              v-if="record.type === 1"
              clickword="添加菜单"
              title="添加菜单"
              click="link"
              :data-source="ADD_MENU_FORM"
              icon="empty"
              @change="(req) => addMenu(req, record.id)"
            />
            <AddDrawer
              v-if="record.type === 2"
              clickword="添加按钮"
              title="添加按钮"
              click="link"
              narrow
              :data-source="ADD_BUTTON_FORM"
              icon="empty"
              @change="(req) => addButton(req, record.id)"
            />
          </a-space>
        </template>
      </a-table>
    </a-card>
  </div>
</template>

<script lang="ts">
  import { Message, TableColumnData } from '@arco-design/web-vue';
  import { MenuRecord } from '@/api/system/model/menuModel';
  import {
    queryMenuRecordTree,
    saveMenuRecord,
    updateMenuRecord,
    deleteMenuRecord,
  } from '@/api/system/menu';
  import { defineComponent, ref, onMounted } from 'vue';
  import TableSearch from '@/common/components/cac-components/advanced-search/index.vue';
  import AddDrawer from '@/common/components/cac-components/advanced-drawer/index.vue';

  export default defineComponent({
    components: { TableSearch, AddDrawer },
    setup() {
      // 查询表单
      const SEARCH_FORM: any[] = [
        { fieldName: 'name', labelText: '菜单名称', type: 'text' },
        { fieldName: 'code', labelText: '菜单编码', type: 'text' },
        { fieldName: 'permission', labelText: '权限标识', type: 'text' },
      ];

      const loading = ref<boolean>(false);

      // func: 查询菜单
      const searchMenu = async () => {
        loading.value = true;
        try {
          const { data } = await queryMenuRecordTree();
          menuList.value = data;
        } finally {
          loading.value = false;
        }
      };

      onMounted(() => {
        searchMenu();
      });

      // 表格
      const menuList = ref<MenuRecord[]>([]);
      const COLUMNS_ROLE: TableColumnData[] = [
        {
          title: '序号',
          align: 'center',
          dataIndex: 'index',
          width: 120,
          render: ({ rowIndex }) => rowIndex + 1,
          fixed: 'left',
        },
        {
          title: '状态',
          dataIndex: 'status',
          slotName: 'status',
          width: 80,
          fixed: 'left',
        },
        {
          title: '菜单名称',
          dataIndex: 'name',
          width: 120,
          ellipsis: true,
          tooltip: true,
        },
        {
          title: '菜单编码',
          dataIndex: 'code',
          width: 120,
          ellipsis: true,
          tooltip: true,
        },
        {
          title: '权限标识',
          dataIndex: 'permission',
          width: 230,
          ellipsis: true,
          tooltip: true,
        },
        { title: '菜单类型', dataIndex: 'type', slotName: 'type', width: 90 },
        {
          title: '路由地址',
          dataIndex: 'path',
          width: 120,
          ellipsis: true,
          tooltip: true,
        },
        { title: '菜单图标', dataIndex: 'icon', width: 180, ellipsis: true },
        {
          title: '组件路径',
          dataIndex: 'component',
          width: 230,
          ellipsis: true,
          tooltip: true,
        },
        { title: '显示顺序', dataIndex: 'sort', align: 'center' },
        {
          title: '操作',
          dataIndex: 'operation',
          slotName: 'operation',
          width: 190,
          align: 'center',
          fixed: 'right',
        },
      ];

      // 树形表格：展开控制
      const expandedRowKeys = ref<(string | number)[]>([]);
      const onExpandRow = (rowKey: string | number) => {
        expandedRowKeys.value = [...expandedRowKeys.value, rowKey];
      };
      const onExpandChange = (rowKeys: (string | number)[]) => {
        expandedRowKeys.value = [...rowKeys];
      };

      // 表单选择器：状态
      const STATUS_OPTIONS: { label: string; value: number }[] = [
        { label: '启用', value: 0 },
        { label: '禁用', value: 1 },
      ];

      // 表单选择器：数据分析范围
      const TYPE_OPTIONS: { label: string; value: number }[] = [
        { label: '目录', value: 1 },
        { label: '菜单', value: 2 },
      ];

      // 抽屉：新增菜单
      const ADD_MENU_FORM: any[] = [
        { labelText: '菜单名称', fieldName: 'name', col: 12 },
        {
          labelText: '菜单编码',
          fieldName: 'code',
          col: 12,
        },
        {
          type: 'select',
          labelText: '菜单类型',
          fieldName: 'type',
          col: 12,
          allowSearch: false,
          codefield: 'value',
          namefield: 'label',
          options: TYPE_OPTIONS,
          initialValue: 2,
        },
        { labelText: '路由地址', fieldName: 'path', col: 12 },
        { labelText: '菜单图标', fieldName: 'icon', col: 12 },
        { labelText: '组件路径', fieldName: 'component', col: 12 },
        { type: 'number', labelText: '显示顺序', fieldName: 'sort', col: 12 },
        {
          type: 'select',
          labelText: '状态',
          allowSearch: false,
          fieldName: 'status',
          codefield: 'value',
          namefield: 'label',
          options: STATUS_OPTIONS,
          initialValue: 0,
          col: 12,
        },
      ];

      // func: 新增菜单或添加菜单
      // 有parentId创建子菜单
      // 无则是一级菜单
      const addMenu = async (req: MenuRecord, parentId?: string) => {
        let menuData: MenuRecord = { ...req };
        if (parentId) {
          menuData = {
            ...menuData,
            parentId,
          };
        }
        try {
          await saveMenuRecord(menuData);
          Message.success('新增成功');
        } finally {
          searchMenu();
        }
      };

      // 抽屉：编辑菜单
      const EDIT_MENU_FORM: any[] = [
        { labelText: '菜单名称', fieldName: 'name', col: 12 },
        {
          labelText: '菜单编码',
          fieldName: 'code',
          col: 12,
        },
        {
          type: 'select',
          labelText: '菜单类型',
          fieldName: 'type',
          col: 12,
          allowSearch: false,
          codefield: 'value',
          namefield: 'label',
          options: TYPE_OPTIONS,
        },
        { labelText: '路由地址', fieldName: 'path', col: 12 },
        { labelText: '菜单图标', fieldName: 'icon', col: 12 },
        { labelText: '组件路径', fieldName: 'component', col: 12 },
        { type: 'number', labelText: '显示顺序', fieldName: 'sort', col: 12 },
        {
          type: 'select',
          labelText: '状态',
          allowSearch: false,
          fieldName: 'status',
          codefield: 'value',
          namefield: 'label',
          options: STATUS_OPTIONS,
          col: 12,
        },
      ];

      // func: 编辑菜单
      const editMenu = async (req: MenuRecord, record: MenuRecord) => {
        try {
          await updateMenuRecord({
            ...req,
            id: record.id,
          });
          Message.success('修改成功');
        } finally {
          searchMenu();
        }
      };

      // func: 删除菜单
      const deleteMenu = async (row: MenuRecord) => {
        try {
          await deleteMenuRecord([row.id] as string[]);
          Message.success('删除成功');
        } finally {
          searchMenu();
        }
      };

      // 抽屉： 添加按钮
      const ADD_BUTTON_FORM: any[] = [
        { labelText: '按钮名称', fieldName: 'name', col: 24 },
        {
          labelText: '权限标识',
          fieldName: 'permission',
          col: 24,
        },
        { type: 'number', labelText: '显示顺序', fieldName: 'sort', col: 24 },
        {
          type: 'select',
          labelText: '状态',
          allowSearch: false,
          fieldName: 'status',
          codefield: 'value',
          namefield: 'label',
          options: STATUS_OPTIONS,
          initialValue: 0,
          col: 24,
        },
      ];

      // func: 添加按钮
      const addButton = async (req: MenuRecord, parentId: string) => {
        try {
          await saveMenuRecord({
            ...req,
            type: 3, // 按钮类型
            parentId,
          });
          Message.success('新增成功');
        } finally {
          searchMenu();
        }
      };

      // 抽屉：编辑按钮
      const EDIT_BUTTON_FORM: any[] = [
        { labelText: '按钮名称', fieldName: 'name', col: 24 },
        {
          labelText: '权限标识',
          fieldName: 'permission',
          col: 24,
        },
        { type: 'number', labelText: '显示顺序', fieldName: 'sort', col: 24 },
        {
          type: 'select',
          labelText: '状态',
          allowSearch: false,
          fieldName: 'status',
          codefield: 'value',
          namefield: 'label',
          options: STATUS_OPTIONS,
          initialValue: 0,
          col: 24,
        },
      ];

      return {
        // 查询
        SEARCH_FORM,
        searchMenu,

        // 表格
        COLUMNS_ROLE,
        menuList,
        loading,
        editMenu,
        deleteMenu,
        expandedRowKeys,
        onExpandRow,
        onExpandChange,

        // 抽屉：新增
        addMenu,
        ADD_MENU_FORM,
        addButton,
        ADD_BUTTON_FORM,

        // 抽屉：修改
        EDIT_MENU_FORM,
        EDIT_BUTTON_FORM,
      };
    },
  });
</script>

<style lang="less" scoped>
  .list-card-container {
    padding: 20px;
    // background-color: var(--color-bg-1);
    border-radius: var(--border-radius-default);
  }
</style>
